<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2020/7/27
 * Time: 13:31
 *
 */

namespace app\service;


use Redis\Redis;
use think\Db;

class jobService
{
    static $_redis;
    static $_value_section;
    static $_checked_array;
    static $_team_id;
    static $_member_code;
    static $_plurs_grid;
    static $not_precedence;
    function __construct()
    {
        self::$_redis=new Redis();
    }

    /***
     * @param $code
     * @param $level
     * @param $grid
     * @param $data
     * @param $team_id
     * @return array
     * @throws \think\Exception
     * @throws \think\exception\PDOException
     * @context 开始匹配方法
     */
    function startMatch($code,$level,$grid,$data,$team_id)
    {
        $team=Db::table("team")->field("id")->where(array("id"=>$team_id))->find();
        if(empty($team)){
            $team_id=null;
        }
        # 查询用户当前有多少空闲栏位
        $plurs_grid=Db::table("member_business_grid")->where(array("member_business_id"=>0,"status"=>1))->count();
        # 将用户栏位改为匹配中
        $res=Db::table("member_business_grid")->where(array("member_code"=>$code,"grid"=>$grid))->update(array("status"=>4,"start_time"=>date('Y-m-d H:i:s')));
        # 修改缓存中用户栏位数据
        $member_business=self::$_redis->hGetJson("member_business",$code);
        $member_business[$grid-1]['open_status']=4;
        $member_business[$grid-1]['start_time']=date('Y-m-d H:i:s');
        self::$_redis->hSetJson("member_business",$code,$member_business);
        if(empty($data['value_section'])){
            $BusinessService=new BusinessService();
            $data['value_section']=$BusinessService->getCanUseValueSection($level);
        }
        $_column_section=array();
        foreach($data['value_section'] as $k=>$v){
            array_push($_column_section,$v[0]);
            array_push($_column_section,$v[1]);
        }
        $min=min($_column_section);
        $max=max($_column_section);
        if(!empty($team_id)){
            $num=self::$_redis->hGet("team".$team_id."level".strval($level),$min."~".$max);
            if(empty($num)){
                $num=0;
            }
            $num+=1;
            self::$_redis->hSet("team".$team_id."level".strval($level),$min."~".$max,strval($num));
        }
        # 调用匹配信息
        jobService::jobMatching($code,$level,$grid,$data,$team_id,$plurs_grid);
        if($res){
            return array("status"=>true);
        }else{
            return array("status"=>false);
        }
    }

    /**
     * @param $code
     * @param $grid
     * @return array
     * @throws \think\Exception
     * @throws \think\exception\PDOException
     * @context 用户取消匹配
     */
    function cancelMatching($code,$grid)
    {
       $listen=self::$_redis->hGetJson("matchListen",$code."and".$grid);
       $data=$listen['data'];
       $team_id=$listen['team_id'];
       $level=$listen['level'];
        $_column_section=array();
        if(!empty($data['value_section']) and !empty($team_id)){
            foreach($data['value_section'] as $k=>$v){
                array_push($_column_section,$v[0]);
                array_push($_column_section,$v[1]);
            }
            $min=min($_column_section);
            $max=max($_column_section);
            $num=self::$_redis->hGet("team".$team_id."level".strval($level),$min."~".$max);
            if(!empty($num)){
                $num-=1;
                if($num==0){
                    self::$_redis->hDel("team".$team_id."level".strval($level),$min."~".$max);
                }else{
                    self::$_redis->hSet("team".$team_id."level".strval($level),$min."~".$max,strval($num));
                }

            }
        }

        self::$_redis->hDel("matchListen",$code."and".$grid);
        self::$_redis->hDel("userMatchBussiness",$code."and".$grid);
        # 将用户栏位改为可匹配
        Db::table("member_business_grid")->where(array("member_code"=>$code,"grid"=>$grid))->update(array("status"=>1));
        $list=self::$_redis->hGetJson("member_business",$code);
        $list[$grid-1]['open_status']=1;
        self::$_redis->hSetJson("member_business",$code,$list);
        return array("status"=>true);
    }

    /**
     * @param $code
     * @param $level
     * @param $grid
     * @param $data
     * @throws \think\Exception
     * @throws \think\exception\PDOException
     * @context 匹配玩家生意
     */
    function jobMatching($code,$level,$grid,$data,$team_id,$plurs_grid)
    {
        ignore_user_abort(TRUE);// 设定关闭浏览器也执行程序
        set_time_limit(0);      // 设定响应时间不限制，默认为30秒
        $matchListen=self::$_redis->hGetJson("matchListen",$code."and".$grid);
        if(empty($matchListen)){
            $matchListen=array("code"=>$code,"level"=>$level,"grid"=>$grid,"data"=>$data,"team_id"=>$team_id,
                "time"=>time(),"log_num"=>0,"plurs_grid"=>$plurs_grid);
            self::$_redis->hSetJson("matchListen",$code."and".$grid,$matchListen);
        }
        $_sleep=60;
        $log_num=$matchListen['log_num'];
        while(true){
            $log_num++;
            $is_continue=self::$_redis->hGetJson("matchListen",$code."and".$grid);
            if(empty($is_continue)){
                # 用户取消匹配
                self::$_redis->hDel("userMatchBussiness",$code."and".$grid);
                break;
            }
            $checkjob=self::checkoutMemberJob($code,$grid,$level);
            if($checkjob["status"]){
                $matchListen['time']=time();
                $matchListen['log_num']=$log_num;
                self::$_redis->hSetJson("matchListen",$code."and".$grid,$matchListen);
                $_sale=self::checkMemberSaleJob($code,$level,$data['value_section'],$checkjob['checked_array'],$team_id,$grid,$checkjob['nowcount'],$plurs_grid);
                if(!$_sale){
                    sleep(15);
                }else{
                    sleep(15);
                }
            }else{
                if(!empty($team_id)){
                    $_column_section=array();
                    foreach($data['value_section'] as $k=>$v){
                        array_push($_column_section,$v[0]);
                        array_push($_column_section,$v[1]);
                    }
                    $min=min($_column_section);
                    $max=max($_column_section);
                    $num=self::$_redis->hGet("team".$team_id."level".strval($level),$min."~".$max);
                    if(!empty($num)){
                        $num-=1;
                        if($num==0){
                            self::$_redis->hDel("team" . $team_id . "level" . strval($level), $min . "~" . $max);
                        }else {
                            self::$_redis->hSet("team" . $team_id . "level" . strval($level), $min . "~" . $max, strval($num));
                        }
                    }
                }
                break;
            }

        }
    }

    /**
     * @param $code 用户 id
     * @param $grid 用户栏位
     * @return bool
     * @context 检查用户是否已经匹配成功
     */
    /**
     * @param $code 用户 id
     * @param $grid 用户栏位
     * @return array
     * @throws \think\Exception
     * @throws \think\exception\PDOException
     * @context 检查用户是否已经匹配成功
     */
    static function checkoutMemberJob($code,$grid,$level)
    {
        $list=self::$_redis->hGetJson("userMatchBussiness",$code."and".$grid);
        if(empty($list)){
            $list=array();
        }
        # 判断该用户需要匹配多少条数据
        $need_count=self::$_redis->hGet("userMatchCount",$code."and".$grid);
        if(empty($need_count)){
            # 判断当前出售的数量是否大于8
            $level_array=MatchingLevelPublic($level);
            $_now_sale_count=0;
            foreach($level_array as $k=>$v){
                $sale_array=self::$_redis->hGetJson("member_sale_bussiness",$v);
                if(!empty($sale_array)){
                    $_now_sale_count+=count($sale_array);
                }
            }
            if($_now_sale_count>=8){
                $need_count=8;
            }elseif($_now_sale_count>=4){
                $need_count=$_now_sale_count;
            }else{
                $need_count=4;
            }
            self::$_redis->hSet("userMatchCount",$code."and".$grid,$need_count);
        }else{
            # 如果匹配100次仍没有匹配到 降低匹配数量 但不能小于4
            if($need_count>4){
                $log_num=self::$_redis->hGetJson("matchListen",$code."and".$grid);
                if(intval($log_num['log_num'])%100==0){
                    $need_count-=1;
                    self::$_redis->hSet("userMatchCount",$code."and".$grid,$need_count);
                }
            }
        }
        # 判断是否选择了最大值和最小值
        $min_and_max=self::$_redis->hGetJson("userMatchMinAndMax",$code."and".$grid);
        if(empty($min_and_max)){
            self::$_redis->hSetJson("userMatchMinAndMax",$code."and".$grid,array("min"=>1,"max"=>1));
        }
        if(is_array($list) and count($list)>=$need_count){
            # 删除需匹配的数量
            self::$_redis->hDel("userMatchCount",$code."and".$grid);
            self::$_redis->hDel("userMatchMinAndMax",$code."and".$grid);
            # 将用户栏位改为匹配成功
            Db::table("member_business_grid")->where(array("member_code"=>$code,"grid"=>$grid))->update(array("status"=>5,"start_time"=>date("Y-m-d H:i:s"),
                "end_time"=>date("Y-m-d H:i:s",strtotime('+1 hours')),"pract_end_time"=>date("Y-m-d H:i:s",strtotime('+1 hours'))));
            # 修改用户缓存中栏位状态
            $member_business=self::$_redis->hGetJson("member_business",$code);
            $member_business[$grid-1]['open_status']=5;
            $member_business[$grid-1]['start_time']=date("Y-m-d H:i:s");
            $member_business[$grid-1]['end_time']=date("Y-m-d H:i:s",strtotime('+1 hours'));
            $member_business[$grid-1]['pract_end_time']=date("Y-m-d H:i:s",strtotime('+1 hours'));
            self::$_redis->hSetJson("member_business",$code,$member_business);
            self::$_redis->hDel("matchListen",$code."and".$grid);
            # 向用户发送匹配成功消息
            $a = new IGeTuiService();
            $content = '生意匹配成功';
            $title = '匹配成功';
            $text = '您成功匹配了一个生意';
            $rep = $a->pushMessageToSingle($content, $title, $text, $code,2);
            return array("status"=>false);
        }else{
            return array("status"=>true,"checked_array"=>array_column($list,"id"),"nowcount"=>count($list));
        }
    }
    /**
     * @param $code      用户id
     * @param $level      用户等级
     * @param $value_section    价值区间数组
     * @param $_checked_array  已选择过的生意
     * @return bool
     * @context 检查出售队列中是否还有未匹配的数据
     */
    static function checkMemberSaleJob($code,$level,$value_section,$_checked_array,$team_id,$grid,$nowcount,$plurs_grid)
    {
        $list=array();
        self::$_value_section=$value_section;
        self::$_checked_array=$_checked_array;
        self::$_team_id=$team_id;
        self::$_member_code=$code;
        self::$_plurs_grid=$plurs_grid;
        # 获取等级对应的匹配等级数组
        $level_array=MatchingLevelPublic($level);
        $grid_arr = ['buy_grid' =>$grid];
        # 获取当前应匹配多少个
        $need_count=self::$_redis->hGet("userMatchCount",$code."and".$grid);
        # 获取是否已经选择完最高等级和最低等级
        $min_and_max=self::$_redis->hGetJson("userMatchMinAndMax",$code."and".$grid);
        foreach($level_array as $k=>$v){
           $sale_array=self::$_redis->hGetJson("member_sale_bussiness",$v);
           if(!empty($sale_array)){
               $new_array=array_values(array_filter($sale_array,"self::filterArray"));
               if(count($new_array)>0){
                    if($v==min($level_array) and $min_and_max['min']==1){
                        # 如果是最低等级的看需要几个
                        $min_and_max['min']=0;
                        self::$_redis->hSetJson("userMatchMinAndMax",$code."and".$grid,$min_and_max);
                        # 对搜索结果按出售价格进行排序
                        array_multisort(array_column($new_array, 'sale_price'), SORT_ASC, $new_array);
                        if($need_count>4){
                            $new_array=array_slice($new_array,0,2);
                            $list=array_merge($list,$new_array);
                        }else{
                            array_push($list,$new_array[0]);
                        }
                    }elseif($v==max($level_array) and $min_and_max['max']==1){
                        # 如果是最高等级的看需要几个
                        $min_and_max['max']=0;
                        self::$_redis->hSetJson("userMatchMinAndMax",$code."and".$grid,$min_and_max);
                        # 对搜索结果按出售价格进行排序
                        array_multisort(array_column($new_array, 'sale_price'), SORT_DESC, $new_array);
                        if($need_count>4){
                            $new_array=array_slice($new_array,0,2);
                            $list=array_merge($list,$new_array);
                        }else{
                            array_push($list,$new_array[0]);
                        }
                    }else{
                        # 中间等级的随机匹配
                        $_rand=rand(0,count($new_array)-1);
                        if(!empty($new_array[$_rand])){
                            $new_array=$new_array[$_rand];
                            array_push($list,$new_array);
                        }
                    }
               }
           }
        }
        if(empty($list)){
            # 判断后匹配数组中是否有值
//                   $file  = 'log.txt';
//                   $content = "走这里了\n";
//                   file_put_contents($file, $content,FILE_APPEND);
            if(!empty(self::$not_precedence)){
                if(count(self::$not_precedence)>0){
                    foreach(self::$not_precedence as $npk=>$npv){
                        if(!in_array($npv['id'],self::$_checked_array)){
                            array_push(self::$_checked_array,$npv['id']);
                            $list=array_merge($list,array($npv));
                            break;
                        }
                    }
                }
            }
        }
        if(empty($list)){
            return false;
        }else{
            array_walk($list, function (&$value, $key, $grid_arr) {
                $value = array_merge($value, $grid_arr);
            },$grid_arr);

            # 填入用户匹配数据
            $mb=self::$_redis->hGetJson("userMatchBussiness",$code."and".$grid);
            if(empty($mb)){
                $mb=array();
            }
            $mb=array_merge($mb,$list);
            self::$_redis->hSetJson("userMatchBussiness",$code."and".$grid,$mb);
            return true;
        }

    }

    /**
     * @param $arr
     * @return bool
     * @context 筛选匹配数据
     */
    static function filterArray($arr)
    {

        if(in_array($arr['id'],self::$_checked_array)){
            return false;
        }else{
            if($arr['member_code']==self::$_member_code){
                return false;
            }
            # 判断是否为投放行业
            if(!empty($arr['lanunch']) and $arr['lanunch']==2){
                # 判断是否有剩余栏位限制
                if($arr['plurs_grid']>0 and $arr['plurs_grid']>self::$_plurs_grid){
                    return false;
                }
                # 判断是否有优先级限制
                if($arr['precedence']==2){
                    # 放入后匹配数组
                    if(empty(self::$not_precedence)){
                        self::$not_precedence=array();
                        array_push(self::$not_precedence,$arr);
                    }else{
                        # 不在后匹配数组中 放入
                        if(!in_array($arr['id'],array_values(array_column(self::$not_precedence,'id')))){
                            array_push(self::$not_precedence,$arr);
                        }
                    }
                    return false;
                }

            }
            if(!empty($arr['team_id'])){
                $_team_collon=explode(',',$arr['team_id']);
                if(!empty(self::$_team_id) and !in_array(self::$_team_id,$_team_collon)){
                    return false;
                }
            }
            $_continue=false;
            foreach(self::$_value_section as $k=>$v){
                if($arr['sale_price']>=$v[0] and $arr['sale_price']<$v[1]){
                    $_continue=true;
                    break;
                }
            }
            if(!$_continue){
                return false;
            }
            return true;
        }
    }


    /**
     * @throws \think\Exception
     * @throws \think\exception\PDOException
     * @context 交易成功卖家2小时确认定时任务执行
     */
    function timedTaskExec()
    {

        a:$list=self::$_redis->hGet("timedTask");
        if(!empty($list)){
            $_first_key=key($list);
            $_first=json_decode(current($list),true);
            // 投诉状态
            if($_first["complaint"]!=1){
                # 删除本条
                self::$_redis->hDel("timedTask",$_first_key);
                goto a;
            }
            if($_first['end_time']<=date("Y-m-d H:i:s")){
                self::$_redis->hDel("timedTask",$_first_key);
                $data=Db::table("trad_audit")->where(array("id"=>$_first['trad_audit_id']))->find();
                $data['sell_id'] = $data['industry_id'];
                self::successTrade($data);
            }
        }
    }

    /**
     * @throws \think\Exception
     * @throws \think\exception\PDOException
     * @context 匹配断开后续接
     */
    function listenTaskExecc()
    {
        if(21<=intval(date("H")) or intval(date("H"))<8){
            return false;
        }
        $_listen_time=self::$_redis->hGet("listen_time","listen_time");
        if(empty($_listen_time)){
            self::$_redis->hSet("listen_time","listen_time",1,30);
            $matchListen=self::$_redis->hGet("matchListen");
            if(!empty($matchListen)){
                foreach($matchListen as $k=>$v){
                    $v=json_decode($v,true);
                    if(time()-$v['time']>=60){
                        $v['time']=time();
                        self::$_redis->hSetJson("matchListen",$v['code']."and".$v['grid'],$v);
                        jobService::jobMatching($v['code'],$v['level'],$v['grid'],$v['data'],$v['team_id'],$v['plurs_grid']);
                        continue;
                    }else{
                        continue;
                    }
                }
            }
        }
    }

    static function levelDeduct()
    {
        return [
            [0.03,0.005],
            [0.03,0.005],
            [0.03,0.005],
            [0.04,0.01],
            [0.04,0.01],
            [0.04,0.01],
            [0.05,0.015],
            [0.05,0.015],
            [0.05,0.015],
            [0.06,0.02],
            [0.06,0.02],
            [0.06,0.02],
        ];
    }

    static function getLevelDeduct($level)
    {
        $list=self::levelDeduct();
        return $list[$level-1];
    }
    /**
     * @param $data
     * @return array
     * @throws \think\Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @throws \think\exception\PDOException
     * @context 玩家确认交易
     */
    static function successTrade($data)
    {
        $sell_list=Db::table("member_business")->where(array("id"=>$data['sell_id']))->find();
        if($sell_list==-1){
            return array("status"=>false,"msg"=>"生意已出售");
        }
        $already_buy=Db::table("member_business_grid")->field("status")->where(array("member_code"=>$data['buy_code'],"grid"=>$data['buy_grid']))->find();
        # 如果不是待卖家付款状态
        if($already_buy['status']!=6){
            return array("status"=>false,"msg"=>"买家栏位发生变化，不可交易");
        }
        # 卖家生意改为已出售
        Db::table("member_business")->where(array("id"=>$data['sell_id']))->update(array("status"=>-1,"trade_finish_time"=>date("Y-m-d H:i:s")));
        if ($sell_list['lanunch']==1){
            Db::table("member_property")->where(array("member_code"=>$sell_list['member_code']))->setInc('income',$sell_list['earnings_price']);
            $memberInfo =  self::$_redis->hGetJson('memberInfo',$sell_list['member_code']);
            if (!empty($memberInfo)) {
                $memberInfo['income'] = priceFormat($memberInfo['income'] + $sell_list['earnings_price']);
                $memberInfo['combat_power'] = Db::table('member_business')->where("member_code = '".$sell_list['member_code']."' and status != -1")->sum('earnings_price');
                self::$_redis->hSetJson('memberInfo', $sell_list['member_code'], $memberInfo);
            }
            MemberService::addLog_income($sell_list['member_code'], $sell_list['earnings_price'], 3);
        }
        # 查询该生意是否在用户栏位里
        if(empty($data['sell_grid'])){
            $in_sale_member_grid=Db::table("member_business_grid")->field("grid")->where(array("member_code"=>$sell_list['member_code'],"member_business_id"=>$sell_list['id']))->find();
            if(!empty($in_sale_member_grid)){
                $data['sell_grid']=$in_sale_member_grid['grid'];
            }
        }
        if(!empty($data['sell_grid'])){
            # 卖家生意和栏位解绑     # 卖家栏位改为打扫中
            Db::table("member_business_grid")->where(array("member_code"=>$data['sell_code'],"grid"=>$data['sell_grid']))
                ->update(array("member_business_id"=>0,"status"=>3, "start_time"=>date("Y-m-d H:i:s"),"end_time"=>date("Y-m-d H:i:s",strtotime("+3 hours")),
                    "pract_end_time"=>date("Y-m-d H:i:s",strtotime("+3 hours"))));
            # 更改卖家栏位缓存
            $sell_member_bussiness=self::$_redis->hGetJson("member_business",$data['sell_code']);
            $sell_member_bussiness[$data['sell_grid']-1]=array("mbg_id"=>$sell_member_bussiness[$data['sell_grid']-1]['mbg_id'],"open_status"=>3,"grid"=>$data['sell_grid'],
                "member_business_id"=>0,
                "start_time"=>date("Y-m-d H:i:s"),
                "end_time"=>date("Y-m-d H:i:s",strtotime("+3 hours")),
                "pract_end_time"=>date("Y-m-d H:i:s",strtotime("+3 hours")));
            self::$_redis->hSetJson("member_business",$data['sell_code'],$sell_member_bussiness);

        }else{
            self::$_redis->hDel("wareHouse",$data['sell_code']);
        }
        # 判断距离结束还有多长时间
        if(time()<strtotime($sell_list['opera_end_time'])){
            $diff=intval(strtotime($sell_list['opera_end_time'])-time())/60;
            if($diff>=10){
                $integral=intval($diff*0.1);
                # 增加用户积分
                Db::table("member_property")->where(array("member_code"=>$data['sell_code']))->setInc("integral",$integral);
                $memberInfo=self::$_redis->hGetJson("memberInfo",$data['sell_code']);
                if(!empty($memberInfo)){
                    $memberInfo['integral']+=$integral;
                    self::$_redis->hSetJson("memberInfo",$data['sell_code'],$memberInfo);
                }
            }
        }
        # 删除定时任务
        self::$_redis->hDel("timedTask",strval($data['sell_id']));
        # 买家卡券转移给卖家
        if(!empty($data['voucher_id'])){
            $voucher_info=Db::table("member_voucher")->where(array("id"=>$data['voucher_id']))->find();
            # 修改为已使用
            Db::table("member_voucher")->where(array("id"=>$data['voucher_id']))->update(array("use_status"=>2));
            # 给卖家增加一张卡券
            unset($voucher_info['id']);
            $voucher_info['member_code']=$data['sell_code'];
            $voucher_info['expiration_time']=date("Y-m-d H:i:s",strtotime("+".$voucher_info['voucher_perioy']." days"));
            $voucher_info['get_time']=date("Y-m-d H:i:s");
            $voucher_info['source']=2;
            $voucher_info['use_status']=1;
            Db::table("member_voucher")->insert($voucher_info);
            # 完成使用卡券任务
            TaskService::finishTask($data['buy_code'], 18);
        }
        # 买家加金币
        # 扣除金币
        Db::table('member_property')->where(array('member_code' => $data['sell_code']))->setInc('gold', $data['price']);
        $memberInfo = self::$_redis->hGetJson('memberInfo', $data['sell_code']);
        if (!empty($memberInfo)) {
            $memberInfo['gold'] = priceFormat($memberInfo['gold'] + $data['price']);
            self::$_redis->hSetJson('memberInfo', $data['sell_code'], $memberInfo);
        }
        # 金币记录
        MemberService::addLog_gold($data['sell_code'], $data['price'], 22,$data["buy_code"]);
        # 买家生意和栏位绑定
        # 计算当前出售价格处于哪种收益阶段
        $detail=getsIndustryDetail($sell_list['industry_id']);
        if($data['amount']>=$detail['info']['max_worth']){
            $data['status']=2;
            $data['cycle_period']=$detail['info']['max_period'];
            $data['day_income']=$detail['info']['max_ratio'];
            $data["sale_price"]=$data['amount'];
            $data['earnings_price']=0;
        }else{
            foreach($detail['cycleIncome'] as $k=>$v){
                if($v['min_num']<=$data['amount'] and $data['amount']<$v['max_num']){
                    $data['cycle_period']=$v['cycle_period'];
                    $data['day_income']=$v['day_income'];
                    break;
                }
            }
            $data["sale_price"]=priceFormat($data['amount']+$data['amount']*$data['day_income']);
            $data['earnings_price']=priceFormat($data["sale_price"]-$data['amount']);
        }
        # 给玩家添加生意
        $_array=array("member_code"=>$data["buy_code"],"industry_id"=>$sell_list['industry_id'],"industry_imgurl"=>$sell_list['industry_imgurl'],
            "industry_title"=>$sell_list['industry_title'],"day_income"=>priceFormat($data['day_income']*$data['amount']/$data['cycle_period']),
            "status"=>1,"buy_time"=>date("Y-m-d H:i:s"),"sell_time"=>date("Y-m-d H:i:s",strtotime("+".$data['cycle_period']." days")),
            "growth_cycle"=>$data['cycle_period'],"earnings_ratio"=>$data['day_income'],"earnings_level"=>$sell_list['earnings_level'],
            "earnings_price"=>$data['earnings_price'],"sale_price"=>$data['sale_price'],
            "buy_price"=>$data['amount'],"opera_start_time"=>date("Y-m-d H:i:s"),"place_status"=>1,
            "day_rents"=>priceFormat(floatval($data['day_income']/$data['cycle_period']*$data['amount']*$detail['info']['day_rent']))
        );
        $buy_business_id=Db::table("member_business")->insertGetId($_array);
        $_array['id']=$buy_business_id;
        $_array['member_business_id']=$buy_business_id;
        # 关联买家生意到买家栏位
        Db::table("member_business_grid")->where(array("member_code"=>$data['buy_code'],"grid"=>$data['buy_grid']))
            ->update(array("member_business_id"=>$buy_business_id,"status"=>1));
        # 买家缓存信息更新
        $memberInfo_buy =  self::$_redis->hGetJson('memberInfo',$data['buy_code']);
        $memberInfo_buy['combat_power'] = Db::table('member_business')->where("member_code = '".$data['buy_code']."' and status != -1")->sum('earnings_price');
        self::$_redis->hSetJson('memberInfo', $data['buy_code'], $memberInfo_buy);
        # 完成购买任务
        TaskService::finishTask($data['buy_code'], 9);
        # 完成出售任务
        TaskService::finishTask($data['sell_code'], 8);
        # 更改买家栏位缓存
        $buy_member_business=self::$_redis->hGetJson("member_business",$data['buy_code']);
        $buy_member_business[$data['buy_grid']-1]=array_merge(array("mbg_id"=>$buy_member_business[$data['buy_grid']-1]['mbg_id'],"open_status"=>1,"grid"=>$data['buy_grid']),$_array);
        self::$_redis->hSetJson("member_business",$data['buy_code'],$buy_member_business);
        # 添加交易记录
        Db::table("log_trad")->insert(array("seller_code"=>$data['sell_code'],"buyer_code"=>$data['buy_code'],
            "industry_id"=>$sell_list['industry_id'],"sell_price"=>$data['amount'],"buy_price"=>$data['price'],"industry_imgurl"=>$sell_list['industry_imgurl'],
            "industry_title"=>$sell_list['industry_title'],"growth_cycle"=>$sell_list['growth_cycle'],"earnings_ratio"=>$sell_list['earnings_ratio'],
            "earnings_price"=>$sell_list['sale_price']-$sell_list['buy_price'],"sell_time"=>$sell_list['trade_time'],"buy_time"=>$sell_list['buy_time'],
            "member_business_id"=>$sell_list['id'],"buyer_business_id"=>$buy_business_id,"voucher_id"=>$data['voucher_id'],"voucher_title"=>$data['voucher_title'],
            "voucher_price"=>$data['voucher_price'],"pay_type"=>$data['pay_type'],"screenshot"=>$data['screenshot']));
        # 更改交易审核状态
        Db::table("trad_audit")->where(array("id"=>$data['id']))->update(array("trad_status"=>2,"buyer_business_id"=>$buy_business_id,"confirm_time"=>date("Y-m-d H:i:s")));
        # 给团队加提成
        # 获取该等级下提成比例
        $deduct=self::getLevelDeduct($sell_list['earnings_level']);
        # 获取售卖人的上级
        $sell_p_code=Db::table("member")->field("p_code")->where(array("code"=>$data['sell_code']))->find()['p_code'];
        if(!empty($sell_p_code)){
            # 增加父级成交金额比例的金币 加金币记录
            $p_gold=$sell_list['sale_price']*$deduct[0];
            Db::table("member_property")->where(array("member_code"=>$sell_p_code))->setInc("gold",$p_gold);
            $p_info=self::$_redis->hGetJson("memberInfo",$sell_p_code);
            $p_info['gold']+=$p_gold;
            self::$_redis->hSetJson("memberInfo",$sell_p_code,$p_info);
            Db::table("log_gold")->insert(array("member_code"=>$sell_p_code,"gold_num"=>$p_gold,"type"=>7,"member_business_id"=>$sell_list['id']));
            # 查询祖父级
            $sell_gp_code=Db::table("member")->field("p_code")->where(array("code"=>$sell_p_code))->find()['p_code'];
            if(!empty($sell_gp_code)){
                $gp_gold=$sell_list['sale_price']*$deduct[1];
                Db::table("member_property")->where(array("member_code"=>$sell_gp_code))->setInc("gold",$gp_gold);
                $gp_info=self::$_redis->hGetJson("memberInfo",$sell_gp_code);
                $gp_info['gold']+=$gp_gold;
                self::$_redis->hSetJson("memberInfo",$sell_gp_code,$gp_info);
                Db::table("log_gold")->insert(array("member_code"=>$sell_gp_code,"gold_num"=>$gp_gold,"type"=>7,"member_business_id"=>$sell_list['id']));
            }
        }
        return array("status"=>true);
    }

    /**
     * @throws \think\Exception
     * @throws \think\exception\PDOException
     * @context 未付款保护2小时
     */
    function protectExec(){
        $list=self::$_redis->hGet("trade_protect");
        if(!empty($list)){
            $_first_key=key($list);
            $_first=json_decode(current($list),true);
            if($_first['end_time']<date("Y-m-d H:i:s")){
                # 解除买方绑定状态
                self::recoverSellStatus($_first_key,$_first['sell_grid'],$_first['sell_code'],$_first['buy_code'],$_first['buy_grid']);
            }
        }
    }

    /**
     * @param $timed_key
     * @param $grid
     * @param $member_code
     * @return bool
     * @throws \think\Exception
     * @throws \think\exception\PDOException
     * @context 将卖家生意状态改为可再次出售
     */
    static function recoverSellStatus($timed_key,$grid,$member_code,$buy_code,$buy_grid)
    {
        if(empty($timed_key)){
            return false;
        }
        $is_inner=self::$_redis->hGetJson("trade_protect",strval($timed_key));
        if(!empty($is_inner)){
            # 删除定时任务
            self::$_redis->hDel("trade_protect",$timed_key);
        }
        $data= Db::table("member_business")->where(array("id"=>$timed_key))->find();
        if($data['status']==8){
            # 将卖方绑定状态改为可重新出售
            $businessService=new BusinessService();
            # 更改卖家生意状态
            Db::table("member_business")->where(array("id"=>$timed_key,"status"=>8))->update(array("status"=>3));
            $data['status']=2;
            if(!empty($grid)){
                # 更改卖家栏位状态
                Db::table("member_business_grid")->where(array("member_code"=>$member_code,"grid"=>$grid))->update(array("status"=>1));
                $mark=1;
            }else{
                $mark=2;
            }
            $businessService->saleBusiness($timed_key,$grid,$data,$mark);
        }

        # 买方栏位状态恢复
        $buyer_status=Db::table("member_business_grid")
            ->field("status,sell_business_id")
            ->where(array("member_code"=>$buy_code,"grid"=>$buy_grid))->find();
        if($buyer_status['status']==7 and $buyer_status['sell_business_id']==$timed_key){
            Db::table("member_business_grid")->where(array("member_code"=>$buy_code,"grid"=>$buy_grid))->update(array("status"=>1,"sell_business_id"=>0,"member_business_id"=>0));
            $member_business=self::$_redis->hGetJson("member_business",$buy_code);
            $member_business[$buy_grid-1]['open_status']=1;
            $member_business[$buy_grid-1]['sell_business_id']=0;
            $member_business[$buy_grid-1]['member_business_id']=0;
            self::$_redis->hSetJson("member_business",$buy_code,$member_business);
        }

        return true;
    }

    /**
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @context 同步用户出售生意
     */
    function syncSaleBusiness()
    {
       $_canSync=self::$_redis->hGet("syncSaleBusiness","syncSaleBusiness");
       if(empty($_canSync)){
           self::$_redis->hSet("syncSaleBusiness","syncSaleBusiness","1",3600);
           $list= Db::table("member_business mb")
               ->field("mb.*,m.name,m.phone")
               ->join("member m","m.code=mb.member_code")
               ->where(array("mb.status"=>3))->select();
           if(!empty($list)) {
               $_redis = new Redis();
               foreach ($list as $k => $v) {
                   # 查询是否在用户栏位中
                   $grid = Db::table("member_business_grid")->field("grid")->where(array("member_code" => $v['member_code'], "member_business_id" => $v['id']))->find();
                   if (!empty($grid['grid'])) {
                       $v["sell_grid"] = $grid['grid'];
                   }
                   # 获取用户信息
                   $v['sale_member_name'] = $v['name'];
                   $v['sale_member_phone'] = $v['phone'];
                   unset($v['name'], $v['phone']);
                   # 计算当前出售价格处于哪种收益阶段
                   $detail = getsIndustryDetail($v['industry_id']);
                   foreach ($detail['cycleIncome'] as $ck => $cv) {
                       if ($cv['min_num'] <= $v['sale_price'] and $v['sale_price'] < $cv['max_num']) {
                           $v['cycle_period'] = $cv['cycle_period'];
                           $v['now_day_income'] = $cv['day_income'];
                           break;
                       }
                   }
                   # 获取列表中是否包含这个生意
                   $_sale_list = $_redis->hGetJson("member_sale_bussiness", $v['earnings_level']);
                   if(!empty($_sale_list)){
                       $_id_coll = array_column($_sale_list, 'id');
                       if (!in_array($v['id'], $_id_coll)) {
                           array_push($_sale_list,$v);
                       }
                   }else{
                       $_sale_list=array();
                       array_push($_sale_list,$v);
                   }
                   $_redis->hSetJson("member_sale_bussiness", $v['earnings_level'],$_sale_list);
               }
           }
       }
    }

}